% !TEX TS-program = pdflatex
% !TEX encoding = UTF-8 Unicode

\documentclass[11pt, titlepage]{article} % use larger type; default would be 10pt

\usepackage[utf8]{inputenc} % set input encoding (not needed with XeLaTeX)

%%% Idioma, lletres
\usepackage[catalan]{babel}
\usepackage{t1enc}            % lletres accentuades son caracters

%%% PAGE DIMENSIONS
\usepackage[hmargin=3cm,vmargin=2.5cm]{geometry} % to change the page dimensions
\geometry{a4paper} % or letterpaper (US) or a5paper or....
% \geometry{margins=2in} % for example, change the margins to 2 inches all round
% \geometry{landscape} % set up the page for landscape
%   read geometry.pdf for detailed page layout information

%%% PACKAGES
\usepackage{graphicx} % support the \includegraphics command and options
\usepackage[parfill]{parskip} % Activate to begin paragraphs with an empty line rather than an indent
\usepackage{booktabs} % for much better looking tables
\usepackage{array} % for better arrays (eg matrices) in maths
\usepackage{paralist} % very flexible & customisable lists (eg. enumerate/itemize, etc.)
\usepackage{verbatim} % adds environment for commenting out blocks of text & for better verbatim
\usepackage{alltt}  % including text format in verbatim
\usepackage{subfig} % make it possible to include more than one captioned figure/table in a single float
\usepackage{multirow}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{algorithmic}
\usepackage{listings}
\usepackage[plain]{algorithm}
\usepackage{wrapfig}
\usepackage{color}
\usepackage[table]{xcolor}

% These packages are all incorporated in the memoir class to one degree or another...

%%% HEADERS & FOOTERS
\usepackage{fancyhdr} % This should be set AFTER setting up the page geometry
\pagestyle{fancy} % options: empty , plain , fancy
\renewcommand{\headrulewidth}{0pt} % customise the layout...
\lhead{}\chead{}\rhead{}
\lfoot{}\cfoot{\thepage}\rfoot{}

%%% SECTION TITLE APPEARANCE
\usepackage{sectsty}
\allsectionsfont{\sffamily\mdseries\upshape} % (See the fntguide.pdf for font help)
% (This matches ConTeXt defaults)

%%% ToC (table of contents) APPEARANCE
\usepackage[nottoc,notlof,notlot]{tocbibind} % Put the bibliography in the ToC
\usepackage[titles,subfigure]{tocloft} % Alter the style of the Table of Contents
\renewcommand{\cftsecfont}{\rmfamily\mdseries\upshape}
\renewcommand{\cftsecpagefont}{\rmfamily\mdseries\upshape} % No bold!

% C++ style setup
\lstset{ 
  language=[ISO]C++, 
  basicstyle=\footnotesize\ttfamily, 
  keywordstyle=\color{blue}, 
  identifierstyle=, 
  commentstyle=\color[rgb]{0, 0.5, 0}, 
  stringstyle=\color{red}\ttfamily, 
  showstringspaces=false, 
  tabsize=4,
} 



%%% END Article customizations


%%% The "real" document content comes below...

\title{{\Huge \bf Fonaments Físics de les Tecnologies Informàtiques}\\ \quad \\ Pràctica de Simulació: Moviment Ondulatori}
\author{Óscar Argudo Medrano \and Carlos Sans Garcia}
\date{UPC, quadrimestre primavera 2010/11} % Activate to display a given date or no date (if empty),
         % otherwise the current date is printed 


\begin{document}

\maketitle
\tableofcontents


\newpage


\section{Introducció}

Aquesta pràctica es basa en l'estudi del moviment ondulatori a partir del càlcul numèric de l'equació d'ones i la posterior visualització de l'ona resultant animada en el temps. Al llarg dels diversos apartats, veurem fenòmens com la propagació de l'ona, què passa si fixem els extrems o si estan lliures, fenòmens d'interferència entre ones i la generació d'ones estacionàries.

La pràctica ha estat programada en C++ i hem fet servir Qt per a la interfície i OpenGL per a la visualització de l'ona. Allà on sigui necessari, comentarem alguns aspectes concrets de la implementació sempre i quan tinguin a veure amb la part física de la simulació. No entrarem en detalls de visualització ni interfície.


\vspace{24pt}
\section{Algorisme numèric}

Com se'ns diu a l'enunciat, el comportament dinàmic d'una magnitud ondulatòria $u(x, t)$ ve determinat per l'equacio d'ones següent:
$$
\frac{ \partial^2 \, u(x, t)}{\partial \, t^2} = \nu \, \frac{\partial^2 \, u(x, t)}{\partial \, x^2}
$$

A partir del mètode de les diferències finites, un mètode per al càlcul numèric d'equacions en derivades parcials, s'arriba a l'expressió següent:
$$
u(x, t + \Delta t) = u(x + \Delta x, t) + u(x - \Delta x, t) - u(x, t - \Delta t)
$$

Per calcular l'estat de l'ona a l'instant $t + \Delta t$, ens cal tenir l'estat de l'ona als instants $t$ i $t - \Delta t$. Només ens caldrà tenir tres vectors durant el càlcul. Cadascun d'ells té una discretització de l'ona en $L$ intervals $u(1), \ldots, u(L)$, i cadascun d'ells té una longitud $\Delta x$. Si no es diu el contrari, considerem que la malla es repeteix infinitament, és a dir, que $u(0) = u(L)$ i $u(L+1) = u(1)$. Com a valors fixats, tenim $\nu = 1$, $\Delta x = 1$, $\Delta t = 1$ i $L \ge 100$. Podem ajustar el valor de $L$ i el nombre de repeticions a mostrar en pantalla mitjançant la interfície, veure més detalls a l'apèndix \ref{sec:apInterficie}.

\begin{figure}[h!]
\centering
\includegraphics[scale=0.75]{img/calcul.png}
\caption{Esquema representatiu del càlcul del valor de $u(x, t+\Delta t)$}
\label{fig:calcul}
\end{figure}

\vspace{12pt}

El càlcul numèric és independent de l'ona que vulguem simular, amb l'excepció en alguns casos de les condicions de contorn. A continuació, es mostra el codi corresponent a aquest càlcul. Per a simplificar, mostrem aquí el cas en què només tenim una ona i que les condicions de contorn són aquelles per a una malla que es repeteix indefinidament, és a dir, $u(0) = u(L)$ i $u(L+1) = u(1)$. 

Els noms que hem donat a les variables són:
$$
\begin{array}{l l}
u(x, t)&		\verb|m_ona| \\
u(x, t + \Delta t)&	\verb|res| \\
u(x, t - \Delta t) &	\verb|m_onaPrev| \\
t&			\verb|m_t| \\
\nu&			\verb|m_vel| \\
\Delta x&		\verb|m_dx| \\
\Delta t&		\verb|m_dt| \\
L&			\verb|m_intervals| \\
\end{array}
$$

I el codi corresponent al càlcul numèric:

\vspace{12pt}

\begin{lstlisting}
void GLWidget::computeOna() {
	// vector per a guardar u(x, t + Dt)
	std::vector<double> res (m_intervals);

	// per a cada x_i, actualitzem el valor
	for (int i = 0; i < m_intervals; i++) {
		res[i] =   m_ona[(i - 1 + m_intervals)%m_intervals]
		         + m_ona[(i + 1)%m_intervals] 
		         - m_onaPrev[i];
	}

	// incrementem la variable t
	m_t += m_dt;

	// actualitzem els vectors d'acord amb la nova t
	m_onaPrev = m_ona; 
	m_ona	  = res;
}
\end{lstlisting}

Observar que hem fet anar aritmètica modular per a tenir en compte el cas en què $x - \Delta x$ o  $x + \Delta x$ se surt del vector. Pels casos de condicions de contorn fixades, comentarem els canvis corresponents a l'apartat concret. Si tenim dues ones, fem la simulació de cada ona en vectors separats i després al visualitzar mostrem la suma de les dues. D'aquesta manera, podem mostrar independentment cadascuna de les dues ones i la superposició.


\newpage
\input{a}

\newpage
\input{b}

\newpage
\input{c}

\newpage
\input{d}

\newpage
\input{e}

\newpage
\input{f}

\newpage
\input{g}



\newpage
\appendix

\section{Codi}

Tot seguit, mostrem el codi complet i real de la funció que fa el càlcul numèric de l'ona, així com les funcions per inicialitzar els vectors amb les dades de cada apartat.

\vspace{12pt}

\begin{lstlisting}
void GLWidget::computeOna() {

	// vectors per a u(x, t + Dt)
	std::vector<double> res (m_intervals);
	std::vector<double> res2(m_intervals);

	for (int i = 0; i < m_intervals; i++) {

		// restar la previa u(x, t - Dt)
		res[i]  = - m_onaPrev[i];
		res2[i] = - m_onaPrev2[i];

		// sumar l'esquerra de l'actual u(x - Dx, t)
		double leftval, leftval2;
		if (i - 1 >= 0) {
			leftval  = m_ona [i - 1];
			leftval2 = m_ona2[i - 1];
		}
		else {
			switch (m_apartat) {
				case APARTAT_B:	leftval = 0.0; break;
				case APARTAT_C: leftval = m_ona[0]; break;
				case APARTAT_G: leftval = 0.1*sin(4*PI/m_intervals*m_t); break;
				default:		leftval  = m_ona [m_intervals - 1]; 
								leftval2 = m_ona2[m_intervals - 1];
								break;
			}
		}
		res[i]  += leftval;
		res2[i] += leftval2;

		// sumar la dreta de l'actual u(x + Dx, t)
		double rightval, rightval2;
		if (i + 1 < m_intervals) {
			rightval  = m_ona [i + 1];
			rightval2 = m_ona2[i + 1];
		}
		else {
			switch (m_apartat) {
				case APARTAT_B:	rightval = 0.0; break;
				case APARTAT_C: rightval = m_ona[m_intervals - 1]; break;
				case APARTAT_G: rightval = 0.0; break;
				default:		rightval  = m_ona [0]; 
								rightval2 = m_ona2[0];
								break;
			}
		}
		res[i]  += rightval;
		res2[i] += rightval2;
	}

	// incrementem la variable t
	m_t += m_dt;

	// actualitzem els vectors d'acord amb la nova t
	m_onaPrev  = m_ona;
	m_ona	   = res;
	m_onaPrev2 = m_ona2;
	m_ona2	   = res2;
}

void GLWidget::setValorsA() {
	for (int i = 0; i < m_intervals; i++) {
		m_ona[i]     = exp(-(i*m_dx - 10)*(i*m_dx - 10));
		m_onaPrev[i] = exp(-(i*m_dx - 10 + m_vel*m_dt)*(i*m_dx - 10 + m_vel*m_dt));
		m_ona2[i] = m_onaPrev2[i] = 0;
	}
}

void GLWidget::setValorsB() {
	for (int i = 0; i < m_intervals; i++) {
		m_ona[i]     = exp(-(i*m_dx - 10)*(i*m_dx - 10));
		m_onaPrev[i] = exp(-(i*m_dx - 10 + m_vel*m_dt)*(i*m_dx - 10 + m_vel*m_dt));
		m_ona2[i] = m_onaPrev2[i] = 0;
	}
}

void GLWidget::setValorsC() {
	for (int i = 0; i < m_intervals; i++) {
		m_ona[i]     = exp(-(i*m_dx - 10)*(i*m_dx - 10));
		m_onaPrev[i] = exp(-(i*m_dx - 10 + m_vel*m_dt)*(i*m_dx - 10 + m_vel*m_dt));
		m_ona2[i] = m_onaPrev2[i] = 0;
	}
}

void GLWidget::setValorsD() {
	for (int i = 0; i < m_intervals; i++) {
		m_ona[i]      = exp(-(i*m_dx - 10)*(i*m_dx - 10));
		m_onaPrev[i]  = exp(-(i*m_dx - 10 + m_vel*m_dt)*(i*m_dx - 10 + m_vel*m_dt));
		m_ona2[i]     = exp(-(i*m_dx - 90)*(i*m_dx - 90));
		m_onaPrev2[i] = exp(-(i*m_dx - 90 - m_vel*m_dt)*(i*m_dx - 90 - m_vel*m_dt));
	}
}

void GLWidget::setValorsE() {
	for (int i = 0; i < m_intervals; i++) {
		m_ona[i]      = sin(4*PI*double(i)/m_intervals);
		m_onaPrev[i]  = sin(4*PI*double(i + m_vel * m_dt)/m_intervals); 
		m_ona2[i]     = sin(4*PI*double(i)/m_intervals);
		m_onaPrev2[i] = sin(4*PI*double(i - m_vel * m_dt)/m_intervals);
	}
}

void GLWidget::setValorsF() {
	for (int i = 0; i < m_intervals; i++) {
		m_ona[i]      = sin(10*PI*double(i)/m_intervals);
		m_onaPrev[i]  = sin(10*PI*double(i + m_vel * m_dt)/m_intervals);
		m_ona2[i]     = sin(12*PI*double(i)/m_intervals);
		m_onaPrev2[i] = sin(12*PI*double(i + m_vel * m_dt)/m_intervals);
	}
}

void GLWidget::setValorsG() {
	for (int i = 0; i < m_intervals; i++) {
		m_ona[i]  = m_onaPrev[i] = 0;
		m_ona2[i] = m_onaPrev2[i] = 0;
	}
}
\end{lstlisting}


\newpage
\section{Interfície}
 \label{sec:apInterficie}


\begin{figure}[h!]
\centering
\includegraphics[scale=0.5]{img/interficie.png}
\caption{Interfície del programa realitzat}
\label{fig:interficie}
\end{figure}



\end{document}

